//
//  HSYNetworkManager.m
//  HSY
//
//  Created by 陈浩 on 2017/3/31.
//  Copyright © 2017年 金开门. All rights reserved.
//

#import "HSYNetworkManager.h"
#import "HSYUserCenter.h"
#import "HSYGetTokenRequest.h"
#import <AFNetworking.h>

@interface HSYNetworkManager ()

@property (nonatomic, copy) NSMutableArray *preTasks; //等待执行的任务
@property (nonatomic, strong) HSYGetTokenRequest *tokenTask; //等待执行的任务
@property (nonatomic, assign) NSInteger retryTimes; //请求token重试次数

@property (nonatomic, strong) AFHTTPSessionManager *networkManager;

@end

@implementation HSYNetworkManager

+ (instancetype)sharedInstatce{
    static HSYNetworkManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!manager) {
            manager = [[self alloc] init];

        }
    });
    return manager;
}


- (instancetype)init{
    self = [super init];
    if (self) {
        self.hostURL = TEST_SERVER_ADDRESS;
        self.fileUrl = TEST_UPLOAD_FILES_SERVER_ADDRESS;
        
//        self.hostURL = ONLINE_SERVER_ADDRESS;
//        self.fileUrl = ONLINE_UPLOAD_FILES_SERVER_ADDRESS;
        
        self.networkManager = [AFHTTPSessionManager manager];
        self.networkManager.requestSerializer.timeoutInterval = 30;
    }
    return self;
}

#pragma mark - GETTERS -

- (NSMutableArray *)preTasks{
    if (!_preTasks) {
        _preTasks = [@[] mutableCopy];
    }
    return _preTasks;
}

- (HSYGetTokenRequest *)tokenTask{
    if (!_tokenTask) {
        _tokenTask = [[HSYGetTokenRequest alloc] init];
    }
    return _tokenTask;
}

#pragma mark - PUBLIC METHODS -

+ (void)POST:(HSYRequest *)request success:(HSYSuccessHandler)success failure:(HSYErrorHandler)failure{
    [[self sharedInstatce] POST:request success:success failure:failure];
}

- (void)POST:(HSYRequest *)request success:(HSYSuccessHandler)success failure:(HSYErrorHandler)failure{
    if (request.task.state == NSURLSessionTaskStateRunning) {
        [request.task cancel];
        request.task = nil;
    }

    if ([request needAccessToken] && [HSYUserCenter instatce].accessToken.length == 0) {//需要token
        //1.将block保持在request中
        request.success = success;
        request.failure = failure;
        //2.将request放入等待数组中，token请求成功后再发送请求
        @synchronized (self) {
            [self.preTasks addObject:request];
        }
        //3.请求token
        [self loadTokenSuccess:nil failure:nil];
    }else{
        
        if ([request fileUplaod]) {
            NSURLSessionTask *task = [self.networkManager POST:self.fileUrl parameters:[request buildUrlParams] constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                //以前的方式相同图片会上传，会穿最前面的一张
                for (int i =0; i<request.files.count; i++) {
                    
                    HSYFileModel *model = request.files[i];
                    
                    if (model.fileData != nil) {
                        NSData *data = model.fileData;
                        NSString *fileName = [NSString stringWithFormat:@"%@.%@",model.fileType,model.suffix];
                        NSString *mineTyeStr = model.mimeType;
                        
                        [formData appendPartWithFileData:data name:[NSString stringWithFormat:@"%@",model.fileType] fileName:fileName mimeType:mineTyeStr];
                        
                    }
                    
                }
                
            } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                if (success) {
                    HSYResponse *response = [HSYResponse mj_objectWithKeyValues:responseObject];
                    response.encryptDataResult = [responseObject[HSY_REQUEST_ENCRYPT_DATA_RESULT] mj_JSONObject];
                    success(response);
                }
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                if (failure) {
                    failure(error);
                }
            }];
            request.task = task;
        }else{
            NSURLSessionTask *task = [self.networkManager POST:self.hostURL parameters:[request buildUrlParams] progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                if (success) {
                    HSYResponse *response = [HSYResponse mj_objectWithKeyValues:responseObject];
                    response.encryptDataResult = [responseObject[HSY_REQUEST_ENCRYPT_DATA_RESULT] mj_JSONObject];
                    success(response);
                }
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                if (failure) {
                    failure(error);
                }
            }];
            request.task = task;
        }
    }
}

+ (void)POST:(HSYRequest *)request completionHander:(HSYCompletionHandler)completion{
    [[HSYNetworkManager sharedInstatce] POST:request completionHander:completion];
}
- (void)POST:(HSYRequest *)request completionHander:(HSYCompletionHandler)completion{
    [self POST:request success:^(HSYResponse *response) {
        if (response.resultCode == HSY_REQUEST_CODE_SUCCESS) {
            if (completion) {
                completion(response.encryptDataResult, nil);
            }
        }else{
            if (completion) {
                completion(nil, response.resultMessage);
            }
        }
    } failure:^(NSError *error) {
        if (error.code != NSURLErrorCancelled) {
            if (completion) {
                completion(nil, @"请求失败");
            }
        }else{
            if (completion) {
                completion(nil, nil); //用户取消
            }
        }
    }];
}


#pragma mark - PRIVATE METHODS -

- (void)executeAllWaitingTasks{
    self.retryTimes = 0; //重置
    for (HSYRequest *req in self.preTasks) { //执行所有等待token的请求
        [self POST:req success:req.success failure:req.failure];
    }
    @synchronized (self) {
        [self.preTasks removeAllObjects];
    }
}

- (void)failToGetTokenWithError:(NSError *)err{
    self.retryTimes = 0; //重置
    for (HSYRequest *req in self.preTasks) { //所有等待的请求发送失败通知
        if (req.failure) {
            req.failure(err);
        }
    }
    @synchronized (self) {
        [self.preTasks removeAllObjects];
    }
}

- (void)loadTokenSuccess:(HSYSuccessHandler)success failure:(HSYErrorHandler)failure{
    if ([self.tokenTask isRunning]) return; //如果正在获取token，则退出
    
    if (self.retryTimes == 0) {
        self.retryTimes = 4;
    }
    
    [self POST:self.tokenTask success:^(HSYResponse *response) {
        NSString *token = response.encryptDataResult[@"accessToken"];
        NSString *encryptKey = response.encryptDataResult[@"encryptKey"];

        if (response.resultCode != HSY_REQUEST_CODE_SUCCESS || token.length == 0 || encryptKey.length == 0) {//未获取到token或encryptkey
            
            [self reloadTokenIfNeed];
            
        }else{
            [HSYUserCenter instatce].accessToken = response.encryptDataResult[@"accessToken"];
            [HSYUserCenter instatce].encryptKey = response.encryptDataResult[@"encryptKey"];
            
            [self executeAllWaitingTasks];
        }
    } failure:^(NSError *error) {
        if (error.code != NSURLErrorCancelled) {
            [self reloadTokenIfNeed];
        }else{
            [self failToGetTokenWithError:error];
        }
    }];
}

- (void)reloadTokenIfNeed{
    if (self.retryTimes > 1) {
        self.retryTimes -= 1; //重试次数减1
    }
    
    if (self.retryTimes == 1) { //当重试次数为1时不再重试
        [self failToGetTokenWithError:[NSError errorWithDomain:@"请求超时" code:NSURLErrorTimedOut userInfo:nil]];
        self.retryTimes = 0;
    }else{
        [self loadTokenSuccess:nil failure:nil];
    }
}


@end
